package com.cc.utils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author CongWT
 * @date 2018年1月8日 上午11:00:57
 * @read "集合对象，对象集合 各种操作"
 */
public class CollectionAttributeFilter {

	/*** 版权所有 CongWT */
	private CollectionAttributeFilter() {}
	/**
	 * 
	 * @param items
	 * @param method
	 * @return
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 */
	public static <T> Map<String, T> getMapByProper(List<T> items, String method) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		if(items==null){return null;}
	    Method m;
	    Map<String, T> retMap = new HashMap<>();
		for (int i = 0; i < items.size(); i++) {
			m = items.get(i).getClass().getMethod(method);
			retMap.put(String.valueOf(m.invoke(items.get(i))), items.get(i));
		}
		return retMap;
	}
	

	/**
	 * 在 集合中 找到 最小或最大的值 返回该值
	 * @param items
	 * @param type
	 * @return
	 */
	public static <T> T getObjByList(List<T> items, String type){
		if(items == null || items.get(0) == null){return null;}
		String ret = null;
		int cn;
	    if("MAX".equals(type)){
			for (int i = 0; i < items.size(); i++) {
				for (int j = i; j < items.size(); j++) {
					cn = String.valueOf(items.get(i)).compareTo(String.valueOf(items.get(j)));
					ret = String.valueOf(cn>0?items.get(i):items.get(j));
				}
			}
	    } else if("MIN".equals(type)) {
			for (int i = 0; i < items.size(); i++) {
				for (int j = i; j < items.size(); j++) {
					cn = String.valueOf(items.get(i)).compareTo(String.valueOf(items.get(j)));
					ret = String.valueOf(cn<0?items.get(i):items.get(j));
				}
			}
	    }
		return (T)ret;
	}
	
	/**
	 * 给对象所有 以 ’set‘开头的方法（并且’set‘后面的名称 在 map 中有） 进行 赋值
	 * @param items
	 * @param type
	 * @return
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 */
	public static boolean putPropersByMap(Map<String, Object> map, Object obj) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		if(map == null || obj == null){return false;}
		String key;
		Method[] methods = obj.getClass().getMethods();
		for (int i = 0; i < methods.length; i++) {
			if(methods[i].getName().startsWith("set")){
				key = methods[i].getName().substring(3);
				if(map.containsKey(key)){
					methods[i].invoke(obj, map.get(key));
				}
			}
		}
		return true;
	}
	
	/**
	 * @author CongWT
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 * @throws SecurityException 
	 * @throws NoSuchMethodException 
	 * @Date 2017年8月1日 下午2:44:39
	 * @see 排序
	 *
	 */
	public static <T> List<T> sortListByProper(List<T> objs, String method, boolean desc) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		if(objs == null || method == null){return null;}
		List<T> objret = new ArrayList<>();
		Map<String, T> sMap = buildMapByProper(objs, method);
		List sList = sortList(new ArrayList(sMap.keySet()), desc);
		sList.forEach(no -> objret.add(sMap.get(no)));	// jdk8支持
//		for (String s : sList) {						// jdk8以下支持
//			objret.add(sMap.get(s));
//		}
		return objret;
	}

	/**
	 * @author CongWT
	 * @Date 2017年8月1日 下午12:08:45
	 * @see list<'bject'> 排序
	 *
	 */
	public static <T> List<T> sortList(List<T> objs, boolean desc) {
		if(objs == null){return null;}
		List<T> retmaxt = new ArrayList<>();
		List<T> retmint = new ArrayList<>();
		int i,j;
		T maxt,mint;
		List<T> objsj = new ArrayList<>(objs);
		if(desc){// 倒叙
			for (i = 0; i < objs.size()/2;i++) {
				maxt = objsj.get(0);
				mint = objsj.get(0);
				for (j = 1; j < objsj.size(); j++) {
					if(String.valueOf(objsj.get(j)).compareTo(String.valueOf(maxt)) > 0){
						maxt = objsj.get(j);
					}else if (String.valueOf(objsj.get(j)).compareTo(String.valueOf(mint)) < 0) {
						mint = objsj.get(j);
					}
				}
				objsj.remove(maxt);
				objsj.remove(mint);
				retmint.add(maxt);
				retmaxt.add(0, mint);
			}
			if(objsj.size() == 1){
				retmint.add(objsj.get(0));
			}
			retmint.addAll(retmaxt);
		} else {// 正序
			for (i = 0; i < objs.size()/2;i++) {
				maxt = objsj.get(0);
				mint = objsj.get(0);
				for (j = 1; j < objsj.size(); j++) {
					if(String.valueOf(objsj.get(j)).compareTo(String.valueOf(maxt)) > 0){
						maxt = objsj.get(j);
					}else if (String.valueOf(objsj.get(j)).compareTo(String.valueOf(mint)) < 0) {
						mint = objsj.get(j);
					}
				}
				objsj.remove(maxt);
				objsj.remove(mint);
				retmint.add(mint);
				retmaxt.add(0, maxt);
			}
			if(objsj.size() == 1){
				retmint.add(objsj.get(0));
			}
			retmint.addAll(retmaxt);
		}
		return retmint;
	}
	

	/**
	 * @author CongWT
	 * @Date 2017年8月1日 下午12:08:45
	 * @see list<'bject'> object中反射一个方法(method)获取一个值到 list返回
	 *
	 */
	public static <E, T> List<E> buildListByProper(List<T> objs, String method) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		if(objs == null || method == null){return null;}
		List<E> ret = new ArrayList<>();
		for (T obj : objs) {
			Method methodo = obj.getClass().getMethod(method);
			ret.add((E) methodo.invoke(obj));
		}
		return ret;
	}


	/**
	 * @author CongWT
	 * @return 
	 * @throws SecurityException 
	 * @throws NoSuchMethodException 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 * @Date 2017年8月1日 下午12:08:45
	 * @see list<'bject'> object中反射一个方法(method)获取一个值到 map返回
	 *
	 */
	public static <E, T> Map<E, T> buildMapByProper(List<T> objs, String method) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		if(objs == null || method == null){return null;}
		Map<E, T> ret = new HashMap<>();
		for (T obj : objs) {
			Method methodo = obj.getClass().getMethod(method);
			ret.put((E) methodo.invoke(obj), obj);
		}
		return ret;
	}
	


	/**
	 * @author CongWT
	 * @return 
	 * @throws SecurityException 
	 * @throws NoSuchMethodException 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 * @Date 2017年8月1日 下午12:08:45
	 * @see list<'bject'> object中反射一个方法(method)获取一个值到 map返回
	 *
	 */
	public static <E, T> Map<E, List<T>> buildMapsByProper(List<T> objs, String method) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		if(objs == null || method == null){return null;}
		Map<E, List<T>> ret = new HashMap<>();
		List<T> liststr;
		E ekey;
		objs = new ArrayList<>(objs);
		for (T obj : objs) {
			ekey = (E) obj.getClass().getMethod(method).invoke(obj);
			if(ret.get(ekey) == null){
				liststr = new ArrayList<>();
				liststr.add(obj);
				ret.put(ekey, liststr);
			}else {
				ret.get(ekey).add(obj);
			}
		}
		return ret;
	}
	


	/**
	 * @author CongWT
	 * @return 
	 * @throws SecurityException 
	 * @throws NoSuchMethodException 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 * @Date 2017年8月1日 下午12:08:45
	 * @see list<'bject'> object中反射多个方法(method)获取一个值按多个方法的顺序进行多级排序后放到 List返回
	 *
	 */
	public static <E, T> List<T> buildMapByPropers(List<T> objs, List<String> methods, List<Boolean> desc) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		if(objs == null || methods == null){return null;}
		List<T> ret = new ArrayList<>();
		Map<Object, List<T>> mapList = new HashMap<>();
		List<Object> sList;
		List<String> methodsf;
		List<Boolean> descf;
		objs = new ArrayList<>(objs);
		System.out.println("methods.size()="+methods.size());
		 if (methods.size() > 0) {
			mapList = buildMapsByProper(objs, methods.get(0));
			sList = sortList(new ArrayList<>(mapList.keySet()), desc.get(0));
			System.out.println("________________________________");
			sList.forEach(w -> System.out.println("sortList--"+w));
			System.out.println("________________________________");
			methodsf = new ArrayList<>(methods);
			descf = new ArrayList<>(desc);
			methodsf.remove(0);
			descf.remove(0);
			for (int i = 0; i < sList.size(); i++) {
				List<T> sList2 = buildMapByPropers(mapList.get(sList.get(i)), methodsf, descf);
				ret.addAll(sList2);
			}
		}
		if(ret.size()==0){ret.addAll(objs);}// 终结
		return ret;
	}
	

	public static void main(String[] args) throws InterruptedException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		System.out.println("go-----------------go-----------------go");
//		List<TongGao> objs = new ArrayList<>();
		List<String> methods = new ArrayList<>();
		List<Boolean> desc = new ArrayList<>();
		
//		for (int i = 0; i < 54; i++) {
//			TongGao e = new TongGao();
//			e.setOn(i%3);
//			e.setAttr1((i%2)+"");
//			e.setCread(i+"");
//			if(i%7==0){
//				Thread.sleep(1000);
//			}
////			Thread.sleep((i*i/20)*100);
//			e.setCreateDate(new Date());
//			objs.add(e);
//		}
		methods.add("getOn");
		desc.add(true);
		
		methods.add("getAttr1");
		desc.add(false);

		methods.add("getCreateDate");
		desc.add(false);

		methods.add("getCread");
		desc.add(true);
		
//		objs = buildMapByPropers(objs, methods, desc);
//		objs.forEach(ob -> System.out.println("-ob.getOn()-"+ob.getOn()+"-ob.getAttr1()-"+ob.getAttr1()+"-ob.getCreateDate()-"+ob.getCreateDate()+"-ob.getCread()-"+ob.getCread()));
		System.out.println("over!");
		
//		buildListByProper(objs, "getCreateDate").forEach(me -> System.out.println("date--"+me));
//		sortList(buildListByProper(objs, "getCreateDate"), true).forEach(me -> System.out.println("me--"+me));
//		System.out.println("over!");
		
		
		
	}
	
	
	
	
	
}
